<?php


namespace app\libs\tool;


use app\libs\exception\AuthFailed;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;

class JwtAuth
{
    protected $alg;
    protected $key;
    protected $issuer;

    public function __construct(string $alg, string $key, string $issuer = 'school_order')
    {
        $this->alg = $alg;
        $this->key = $key;
        $this->issuer = $issuer;
    }

    public function create($data = '', int $nbf = 0, int $exp = null): string
    {
        $now = time();

        $payload = [
            'iss' => $this->issuer,
            'aud' => $this->issuer,
            'iat' => $now,
            'nbf' => $now + $nbf,
            'data' => $data
        ];

        if (!empty($exp)) $payload['exp'] = $now + $exp;

        return JWT::encode($payload, $this->key, $this->alg);
    }

    /**
     * @throws AuthFailed
     */
    public function verify(string $jwt)
    {
        try {
            // 当前时间减去60, 吧时间留点余地
            JWT::$leeway = 60;
            $decoded = JWT::decode($jwt, $this->key, [$this->alg]);
            $arr = (array)$decoded;
            $result['code'] = 1;
            $result['data'] = $arr['data'];
            return $result;
        } catch (SignatureInvalidException $e) { // 签名不正确
            throw new AuthFailed(['message' => '签名不正确']);
        } catch (BeforeValidException $e) { // 签名要在某一个时间点后才能使用
            throw new AuthFailed(['message' => '签名已经失效']);
        } catch (ExpiredException $e) { // jwt过期
            throw new AuthFailed(['message' => '签名过期']);
        }catch (\Exception $e) {
            throw new AuthFailed(['message' => '登录状态异常, 请登录']);
        }
    }


}